using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Media;

namespace Trigits
{
    class TrigitsGame : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        BasicEffect basicEffect;

        //Triominoe triominoe;
        SpriteFont triominoeFont;
        Texture2D tableTexture;

        GameTable table;
        SlateContainer[] slateContainers;
        StackContainer stackContainer;

        TriominoeContainer[] containers;
        Triominoe inHand;

        SpriteFont TouchFont;
        Vector2 coordinates = new Vector2(10.0f, 0.0f);

        Vector2 huidigDrag;
        Boolean newDrag = true;
        Vector2 startDrag;
        Vector2 tabVector;

        //images
        Texture2D background;
        Texture2D boardBackground;
        Texture2D stackBackgroundShow;
        Texture2D stackBackgroundHidden;

        public TrigitsGame()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            // Frame rate is 30 fps by default for Windows Phone.
            TargetElapsedTime = TimeSpan.FromTicks(333333);

            // Extend battery life under lock.
            InactiveSleepTime = TimeSpan.FromSeconds(1);
            TouchPanel.EnabledGestures = GestureType.Tap | GestureType.FreeDrag | GestureType.DragComplete;
            
            //landscape view
            graphics.SupportedOrientations = DisplayOrientation.LandscapeLeft;
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            basicEffect = new BasicEffect(graphics.GraphicsDevice);
            basicEffect.VertexColorEnabled = true;
            basicEffect.Projection = Matrix.CreateOrthographicOffCenter
               (0, graphics.GraphicsDevice.Viewport.Width,     // left, right
                graphics.GraphicsDevice.Viewport.Height, 0,    // bottom, top
                0, 1);                                         // near, far plane

            containers = new TriominoeContainer[3];
            slateContainers = new SlateContainer[2];
           

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            tableTexture = Content.Load<Texture2D>("TriominoesTable");
            background = Content.Load<Texture2D>("images/background_trio_variant2");
            boardBackground = Content.Load<Texture2D>("images/board_background");
            stackBackgroundShow = Content.Load<Texture2D>("images/stack_background_show");
            stackBackgroundHidden = Content.Load<Texture2D>("images/stack_background_hidden");

            triominoeFont = Content.Load<SpriteFont>("Triominoe");
            TouchFont = Content.Load<SpriteFont>("Triominoe");

            table = new GameTable(tableTexture, graphics.GraphicsDevice, triominoeFont, 0.8f);

            slateContainers[0] = new SlateContainer("player1", 1, 1, triominoeFont, 6, 
                new Rectangle(50, 10, graphics.GraphicsDevice.Viewport.Width-100, 100), 
                new Rectangle(200, 10, graphics.GraphicsDevice.Viewport.Width-250, 100), boardBackground);
            slateContainers[1] = new SlateContainer("player2", 1, 1, triominoeFont, 6,
                new Rectangle(50, graphics.GraphicsDevice.Viewport.Height - 110, graphics.GraphicsDevice.Viewport.Width - 100, 100),
                new Rectangle(200, graphics.GraphicsDevice.Viewport.Height - 110, graphics.GraphicsDevice.Viewport.Width - 250, 100), boardBackground);

            stackContainer = new StackContainer(
                    new Rectangle(0, (graphics.GraphicsDevice.Viewport.Height / 2) - 150, 300, 300), 
                    new Rectangle(0, (graphics.GraphicsDevice.Viewport.Height / 2) - 150, 100, 300),
                    new Rectangle(0, (graphics.GraphicsDevice.Viewport.Height / 2) - 150, 250, 300),
                    stackBackgroundShow, stackBackgroundHidden, 6, triominoeFont, graphics
                    );
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        Object gestureOrigin = null;
        Object gestureTarget = null;

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            while (TouchPanel.IsGestureAvailable)
            {
                GestureSample gesture = TouchPanel.ReadGesture();

                switch (gesture.GestureType)
                {
                    case GestureType.FreeDrag:
                        {
                            if (gestureOrigin == null)
                            {
                                break;
                            }
                            if (gestureOrigin.GetType() == typeof(Triominoe))
                            {
                                break;
                            }
                            if (gestureOrigin.GetType() == typeof(GameTable))
                            {
                                break;
                            }
                            if (gestureOrigin.GetType() == typeof(StackContainer))
                            {
                                break;
                            }
                            if (gestureOrigin.GetType() == typeof(SlateContainer))
                            {
                                break;
                            }

                            break;
                        }
                    case GestureType.DragComplete:  break;
                    case GestureType.Pinch:         break;
                    case GestureType.PinchComplete: break;
                    case GestureType.Tap:           break;
                    case GestureType.None:          break;
                }
            }

            stackContainer.Update(gameTime, inHand);
            foreach (SlateContainer sl in slateContainers)
                sl.Update(gameTime, inHand);

            base.Update(gameTime);
        }

        public Object getGestureObject(GestureSample gesture)
        {
            // stack
            //stackContainer.
            return null;
        }

        Boolean open = false;

        public Triominoe getTriominoe(float x, float y)
        {
            if (inHand != null)
                return inHand;

            Triominoe t = null;

            if (open)
            {
                TriominoeContainer tc = stackContainer.container;
                if (tc != null)
                    t = tc.getTriominoe(x, y);
                if (t != null) return t;
            }

            //TODO, coordienaten kloppen niet helemaal
            if (t == null)
            {
                foreach (SlateContainer sl in slateContainers)
                {
                    TriominoeContainer tc1 = sl.container;
                    if (tc1 != null)
                        t =  tc1.getTriominoe(x, y);
                    if(t != null) return t;
                }
            }
            return t;
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            
            //background tafel
            spriteBatch.Begin();
                spriteBatch.Draw(background, new Rectangle(0, 0, graphics.GraphicsDevice.Viewport.Width, graphics.GraphicsDevice.Viewport.Height), Color.White);
            spriteBatch.End();

            //stenen op tafel
            spriteBatch.Begin();
                basicEffect.CurrentTechnique.Passes[0].Apply();
                table.Draw(GraphicsDevice, spriteBatch, triominoeFont);
            spriteBatch.End();

            //trio containers

            foreach (SlateContainer sl in slateContainers)
                sl.Draw(GraphicsDevice, spriteBatch, triominoeFont, basicEffect);

            stackContainer.Draw(GraphicsDevice, spriteBatch, triominoeFont, basicEffect);
            base.Draw(gameTime);
        }
    }
}
